<!DOCTYPE html>
<html lang="zh">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>
    
    数组指针与指向数组的指针变量 - DSRBLOG
    
  </title>
  

  
  
  <link href="atom.xml" rel="alternate" title="DSRBLOG" type="application/atom+xml">
  <link rel="stylesheet" href="asset/css/style.min.css">
  <link rel="stylesheet" href="asset/css/doc.css">
  <script src="asset/app.js"></script>


</head>

<body> <section class="ct-body">
	<div class="container">
		<div class="columns is-variable bd-klmn-columns is-4 is-centered">
			<div class="column is-four-fifths">
				<div class="post-body single-content">
					
					<h1 class="title">
						数组指针与指向数组的指针变量
					</h1>


					<div class="media">
						
						
						<div class="media-content">
							<div class="content">
								<p>
									<span class="date">2022/01/19 21:24 下午</span>
									

									

									<br />
									<span class="tran-tags">Tags:</span>&nbsp;
									
									<a class="tag is-link is-light">#C语言</a>
									

								</p>
							</div>
						</div>

					</div>
				</div>
				<article class="markdown-body single-content">
					<h2><a id="%E6%95%B0%E7%BB%84%E6%8C%87%E9%92%88%E4%B8%8E%E6%8C%87%E5%90%91%E6%95%B0%E7%BB%84%E7%9A%84%E6%8C%87%E9%92%88%E5%8F%98%E9%87%8F%E7%9A%84%E5%AE%9A%E4%B9%89" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>数组指针与指向数组的指针变量的定义</h2>
<ul>
<li>
<p>一个数组包含若干元素，每个数组元素都在内存中占用存储单元，都有相应的地址</p>
</li>
<li>
<p>指针变量可以指向数组元素（把某一元素的地址放到一个指针变量中）</p>
</li>
<li>
<p>数组元素的指针就是数组元素的地址</p>
</li>
<li>
<p>指针变量可以进行自加<code>++</code>、自减<code>--</code>，每次<em>移动1个单元</em>，<em>不是1个字节</em>，也可以通过<code>p = p + i</code>一次移动<code>i</code>个单元</p>
</li>
</ul>
<h3><a id="%E4%BE%8B" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>例</h3>
<p>定义一个指向数组元素的指针变量的方法（与指向变量的指针变量相同）</p>
<pre class="line-numbers"><code class="language-c">int a[10];
int *p;
p = &amp;a[0];
</code></pre>
<ul>
<li>定义<code>a</code>为包括10个整型数据的数组</li>
<li>定义<code>p</code>为指向整型变量的指针变量</li>
<li>将<code>a[0]</code>元素的地址赋值给指针变量<code>p</code></li>
</ul>
<p><strong>注意：</strong> 对于一维数组，从值的角度来说，<code>p = &amp;a[0]</code>等价于<code>p = a</code>，指针变量等于数组名</p>
<h2><a id="%E9%80%9A%E8%BF%87%E6%8C%87%E9%92%88%E5%BC%95%E7%94%A8%E6%95%B0%E7%BB%84%E5%85%83%E7%B4%A0" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>通过指针引用数组元素</h2>
<h3><a id="%E4%B8%8B%E6%A0%87%E6%B3%95" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>下标法</h3>
<p>如<code>a[i]</code>形式，<code>i</code>称之为下标或偏移量</p>
<h3><a id="%E6%8C%87%E9%92%88%E6%B3%95" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>指针法</h3>
<p>如<code>*(a+i)</code>或<code>*(p+i)</code>，<code>a</code>是<em>数组名</em>，<code>p</code>是<em>指针变量</em>，<code>i</code>是偏移量，其初值<code>p = a</code></p>
<h3><a id="%E4%BE%8B" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>例</h3>
<p>有一个数组存放10个学生的年龄，用不同的方法输出数组中的全部元素</p>
<h4><a id="%E5%88%86%E6%9E%90" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>分析</h4>
<p>设整型数组<code>a[10]</code>，用不同的方法实现</p>
<ul>
<li>用数组名加下标（如：<code>a[i]</code>）</li>
<li>通过数组名计算数组元素地址，找到元素（如：<code>*(a + i)</code>）</li>
<li>通过指针变量计算数组元素地址，找到元素（如：<code>*(p + i)</code>）</li>
<li>用指针变量先后指向各数组元素（如：<code>*p; p++</code>）</li>
</ul>
<pre class="line-numbers"><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

int main()
{
    int a[10];
    int i;
    int *p = a;

    //给数组a[10]赋初值
    for (i = 0; i &lt; 10; i++)
    {
        a[i] = 10 + rand() % 9;
    }

    //用数组名加下标
    for (i = 0; i &lt; 10; i++)
    {
        printf(&quot;%d &quot;, a[i]);
    }
    printf(&quot;\n\n&quot;);
    //通过数组名计算数组元素地址，找到元素
    for (i = 0; i &lt; 10; i++)
    {
        printf(&quot;%d &quot;, *(a + i));
    }
    printf(&quot;\n\n&quot;);
    //通过指针变量计算数组元素地址，找到元素
    for (i = 0; i &lt; 10; i++)
    {
        printf(&quot;%d &quot;, *(p + i));
    }
    printf(&quot;\n\n&quot;);
    //用指针变量先后指向各数组元素
    for (p = a; p &lt; (a + 10); p++)
    {
        printf(&quot;%d &quot;, *p);
    }
    return 0;
}
</code></pre>
<h2><a id="%E6%95%B0%E7%BB%84%E5%90%8D%E4%BD%9C%E4%B8%BA%E5%87%BD%E6%95%B0%E5%8F%82%E6%95%B0" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>数组名作为函数参数</h2>
<h3><a id="%E4%BE%8B" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>例</h3>
<p>将数组a中N个整数逆序存放，不使用额外的和原空间大小一致的存储空间（原地交换）</p>
<pre class="line-numbers"><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#define N 10

int main()
{
    int a[N];
    int i, t;
    int *p = a;

    //给数组a[N]赋初值
    for (i = 0; i &lt; N; i++)
    {
        a[i] = rand() % 51;
    }

    //输出原顺序
    for (i = 0; i &lt; N; i++)
    {
        printf(&quot;%d &quot;, a[i]);
    }
    printf(&quot;\n&quot;);
    //调换顺序
    for (i = 0; i &lt; (N / 2); i++)
    {
        t = a[i];
        a[i] = a[N - i - 1];
        a[N - i - 1] = t;
    }
    printf(&quot;\n&quot;);
    //输出结果
    for (i = 0; i &lt; N; i++)
    {
        printf(&quot;%d &quot;, a[i]);
    }
    return 0;
}
</code></pre>
<h3><a id="%E5%AE%9E%E5%8F%82%E4%B8%8E%E5%BD%A2%E5%8F%82%E7%9A%84%E5%AF%B9%E5%BA%94%E5%85%B3%E7%B3%BB" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>实参与形参的对应关系</h3>
<p>实参与形参的对应关系有以下4中情况：</p>
<h4><a id="%EF%BC%88%E4%B8%80%EF%BC%89%E5%BD%A2%E5%8F%82%E5%92%8C%E5%AE%9E%E5%8F%82%E9%83%BD%E7%94%A8%E6%95%B0%E7%BB%84%E5%90%8D" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>（一）形参和实参都用数组名</h4>
<p>数组名作为函数参数时进行<code>地址传递</code>，对<code>x[]</code>进行的所有操作都直接影响<code>a[10]</code></p>
<pre class="line-numbers"><code class="language-c">void f(int x[], int n) {}

int main()
{
    int a[10];
    f(a, 10);
    return 0;
}
</code></pre>
<h4><a id="%EF%BC%88%E4%BA%8C%EF%BC%89%E5%AE%9E%E5%8F%82%E7%94%A8%E6%95%B0%E7%BB%84%E5%90%8D%EF%BC%8C%E5%BD%A2%E5%8F%82%E7%94%A8%E6%8C%87%E9%92%88%E5%8F%98%E9%87%8F" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>（二）实参用数组名，形参用指针变量</h4>
<p>对<code>x</code>进行的所有操作都间接的影响对数组<code>a[10]</code>（<em>最常用</em>）</p>
<pre class="line-numbers"><code class="language-c">void f(int *x, int n) {}

int main()
{
    int a[10];
    f(a, 10);
    return 0;
}
</code></pre>
<h4><a id="%EF%BC%88%E4%B8%89%EF%BC%89%E5%BD%A2%E5%8F%82%E5%92%8C%E5%AE%9E%E5%8F%82%E9%83%BD%E7%94%A8%E6%8C%87%E9%92%88%E5%8F%98%E9%87%8F" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>（三）形参和实参都用指针变量</h4>
<p>对<code>x</code>进行的所有操作都间接的影响数组<code>a[10]</code>和<code>p</code>（<em>不常用</em>）</p>
<pre class="line-numbers"><code class="language-c">void f(int *x, int n) {}

int main()
{
    int a[10], *p = a;
    f(p, 10);
    return 0;
}
</code></pre>
<h4><a id="%EF%BC%88%E5%9B%9B%EF%BC%89%E5%AE%9E%E5%8F%82%E4%B8%BA%E6%8C%87%E9%92%88%E5%8F%98%E9%87%8F%EF%BC%8C%E5%BD%A2%E5%8F%82%E4%B8%BA%E6%95%B0%E7%BB%84%E5%90%8D" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>（四）实参为指针变量，形参为数组名</h4>
<p>对<code>x[]</code>进行的所有操作都间接的影响数组<code>a[10]</code>和<code>p</code>（<em>不常用</em>）</p>
<pre class="line-numbers"><code class="language-c">void f(int x[], int n) {}

int main()
{
    int a[10], *p = a;
    f(p, 10);
    return 0;
}
</code></pre>
<h2><a id="%E6%8C%87%E5%90%91%E5%A4%9A%E7%BB%B4%E6%95%B0%E7%BB%84%E5%B8%A6%E7%9A%84%E6%8C%87%E9%92%88%E5%92%8C%E6%8C%87%E9%92%88%E5%8F%98%E9%87%8F" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>指向多维数组带的指针和指针变量</h2>
<pre class="line-numbers"><code class="language-c">int a[2][3] = {1, 2, 3, 4, 5, 6};
int *p;

//下列三种形式等价
p = &amp;a[i][j]; //&amp;号可以抵消最右侧的中括号
p = a[i] + j;
p = *(a + i) + j; //*号可以等价于一个括号
</code></pre>
<h3><a id="%E4%BE%8B" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>例</h3>
<pre class="line-numbers"><code class="language-c">int main()
{
    int a[2][3] = {1, 2, 3, 4, 5, 6};
    int *p, i, j;
    p = &amp;a[0][0]; //或p=*a
    for (i = 0; i &lt; 2; i++)
    {
        for (j = 0; j &lt; 3; j++)
        {
            // p = &amp;a[i][j];
            p = a[i] + j;
            // p = *(a + i) + j;
            printf(&quot;%d &quot;, *p);
        }
        putchar('\n');
    }
    return 0;
}
</code></pre>
<h4><a id="%E6%88%96" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>或</h4>
<pre class="line-numbers"><code class="language-c">int main()
{
    int a[2][3] = {1, 2, 3, 4, 5, 6};
    int *p, i, j;
    p = &amp;a[0][0]; //或p=*a
    for (i = 0; i &lt; 2; i++)
    {
        for (j = 0; j &lt; 3; j++)
        {
            printf(&quot;%d &quot;, *p++); 
            //*号与自加、自减运算优先级一致，从右至左进行运算，先输出p，然后执行自加运算
        }
        putchar('\n');
    }
    return 0;
}
</code></pre>

				</article>
				<div class="comments-wrap">
					<div class="share-comments">
						

						

						
					</div>
				</div><!-- end comments wrap -->
			</div>
		</div><!-- end columns -->
	</div><!-- end container -->
</section>  














<script src="asset/prism.js"></script>









</body>

</html>